package com.dayatang.exam.domain;

import java.util.Date;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.Entity;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.hibernate.annotations.CacheConcurrencyStrategy;

import com.dayatang.domain.AbstractEntity;
import com.dayatang.domain.QuerySettings;

/**
 * 答题。每道答题由�?��试题生成，从属于�?��试卷
 * @author yang
 *
 */
@Entity
@Table(name = "QUESTION_SOLUTIONS")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "CATEGORY", discriminatorType = DiscriminatorType.STRING)
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public abstract class QuestionSolution extends AbstractEntity {

	/**
	 * 
	 */
	private static final long serialVersionUID = 2182604617417673956L;

	/**
	 * �?��试卷
	 */
	@ManyToOne
	@JoinColumn(name = "PAPER_ID", nullable = false)
	private AnswerPaper answerPaper;

	/**
	 * 试题
	 */
	@ManyToOne
	@JoinColumn(name = "QUESTION_ID", nullable = false)
	private Question question;

	/**
	 * 考生答案
	 */
	private String solution;

	/**
	 * 题目分数
	 */
	private int point;

	/**
	 * 得分
	 */
	private int score;
	
	/**
	 * 序号
	 */
	@Column(name = "POSITION")
	private int position;



	public QuestionSolution() {
	}

	public QuestionSolution(Question question, int point, int position) {
		this.question = question;
		this.point = point;
		this.position = position;
	}

	/**
	 * 根据试题和分数生成答�?
	 * @param question
	 * @param point
	 * @return
	 */
	public static QuestionSolution createQuestionSolution(Question question, int point, int position) {
		if (question instanceof SingleChoiceQuestion) {
			return new SingleChoiceSolution((SingleChoiceQuestion) question, point, position);
		}
		if (question instanceof MultiChoiceQuestion) {
			return new MultiChoiceSolution((MultiChoiceQuestion) question, point, position);
		}
		if (question instanceof JudgementQuestion) {
			return new JudgementSolution((JudgementQuestion) question, point, position);
		}
		if (question instanceof FillBlankQuestion) {
			return new FillBlankSolution((FillBlankQuestion) question, point, position);
		}
		if (question instanceof QuizQuestion) {
			return new QuizSolution((QuizQuestion) question, point, position);
		}
		return null;
	}

	public AnswerPaper getAnswerPaper() {
		return answerPaper;
	}

	public void setAnswerPaper(AnswerPaper examPaper) {
		this.answerPaper = examPaper;
	}

	public Question getQuestion() {
		return question;
	}

	public void setQuestion(Question question) {
		this.question = question;
	}

	public String getSolution() {
		return solution;
	}

	public void setSolution(String solution) {
		this.solution = solution;
	}

	public int getPoint() {
		return point;
	}

	public void setPoint(int point) {
		this.point = point;
	}

	public int getScore() {
		return score;
	}

	public void setScore(int score) {
		this.score = score;
	}

	public int getPosition() {
		return position;
	}

	public void setPosition(int position) {
		this.position = position;
	}

	@Override
	public boolean equals(final Object other) {
		if (!(other instanceof QuestionSolution))
			return false;
		QuestionSolution castOther = (QuestionSolution) other;
		return new EqualsBuilder().append(getId(), castOther.getId()).append(question, castOther.question).isEquals();
	}

	@Override
	public int hashCode() {
		return new HashCodeBuilder().append(getId()).append(question).toHashCode();
	}

	@Override
	public String toString() {
		return new ToStringBuilder(this).append("id", getId()).append("question", question).toString();
	}


	public static QuestionSolution get(Long id) {
		return getRepository().get(QuestionSolution.class, id);
	}

	/**
	 * 解答本题�?
	 * @param answer
	 * @throws UpdateSubmittedExamPaperException
	 */
	public void makeAnswer(String answer) throws UpdateSubmittedExamPaperException {
		Date now = new Date();
		if (now.after(answerPaper.getToTime())) {
			answerPaper.submit();
			throw new UpdateSubmittedExamPaperException();
		}
		if (answerPaper.isSubmitted() || answerPaper.isScored()) {
			throw new UpdateSubmittedExamPaperException();
		}
		setSolution(answer);
		save();
	}

	/**
	 * 给本答题评分
	 * @param score2
	 */
	public void makeScore(int score) {
		setScore(score);
		save();
	}

	public static <T extends QuestionSolution> List<T> findByAnswerPaper(AnswerPaper answerPaper, Class<T> solutionClass) {
		return getRepository().find(QuerySettings.create(solutionClass)
				.eq("answerPaper", answerPaper)
				.asc("position"));
	}
}
